#include "54func.h"
#include "clientFunc.h"
#define COMMANDNUM  11

// 返回值为0时, 指令和参数个数是正确的, 将cmd发送给服务端
int parseToken(int sockfd, char *command, cmd_t * pcmd){
    char *token = strtok(command," ");
    if(token ==NULL){
        return -1;
    }
    strcpy(pcmd->cmdToken,token);
    typedef struct argc_s{
        char *commandName;
        int min;
        int max;
    }argc_t;
    argc_t argc[COMMANDNUM]={{"cd",0,1},
        {"ls",0,1},
        {"puts",1,2},
        {"gets",1,2},
        {"login",2,2},
        {"pwd",0,0},
        {"mkdir",1,1},
        {"rm",1,1},
        {"useradd",2,2},
        {"logout",0,0}, 
        {"quit",0,0}};
    argc_t *argcInfo = (argc_t*)calloc(1, sizeof(argc_t));
    int found = 0;//0 输入的命令不符    

// 判断在当前状态下, 指令是否有效
    if(!loginFlag) {
        if(strcmp(pcmd->cmdToken, "login") == 0 || strcmp(pcmd->cmdToken, "useradd") == 0 ||
           strcmp(pcmd->cmdToken, "quit") == 0) {
            found = 1;
        }
        else {
            printf("Please login.\n");
        } 
    }
    else {
        for(int i = 0; i < COMMANDNUM; ++i) {
            if((strcmp(pcmd->cmdToken, argc[i].commandName) == 0) && (i != 4)) {
                found = 1;
            }
            else {
                if(i == 4) {
                    printf("Already login!\n");
                }
                else {
                    printf("Command is not valid!\n");
                }
            }
        }
    }

   // 指令为无效指令, 退出
    if(!found){
        return -1;
    }
    int argNum = 0;

    // 将参数存入pcmd的argv中
    if((token = strtok(NULL, " ")) != NULL) {
        memcpy(pcmd->argv1, token, strlen(token));
        argNum++;
    }
    if((token = strtok(NULL, " ")) != NULL) {
        memcpy(pcmd->argv2, token, strlen(token));
        argNum++;
    }
    if((token = strtok(NULL, " ")) != NULL) {
        argNum++;
    }
    
    // 判断参数个数是否和指令的最大最小参数个数匹配
    if(argNum < argcInfo->min || argNum > argcInfo->max){
        printf("-bash: %s: 参数不匹配!\n",token);
        return -1;
    }
    
    // puts和gets时本地路径是否有效
    bool pathInvalid = true;
    if(strcmp(pcmd->cmdToken, "puts") == 0) {
        char realpath[PATH_MAX] = {0};
        realPath(pcmd->argv1, realpath);
        if(pathJudge(realpath, S_IFDIR) != 1) {
            pathInvalid = false;
        }
    }
    else if(strcmp(pcmd->cmdToken, "gets") == 0) {
        char realpath[PATH_MAX] = {0};
        realPath(pcmd->argv2, realpath);
        if(pathJudge(realpath, S_IFDIR) != 1) {
            pathInvalid = false;
        }
    }
    if(!pathInvalid) {
        return -1;
        printf("Local path is invalid.\n");
    }

    pcmd->argc = argNum;
    //发送结构体cmd_t
    train_t train;
    bzero(&train,sizeof(train));
    train.length = sizeof(cmd_t);
    memcpy(train.data,&pcmd,train.length);
    send(sockfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
   
    return 0;
}   
